package org.example.interfaces.filter;

import com.alibaba.fastjson2.JSON;
import org.example.web.result.BaseErrorCode;
import org.example.web.result.ResultInfo;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class CustomErrorHandlingGatewayFilterFactory implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
        return chain.filter(exchange).then(Mono.defer(() -> {
            ServerHttpResponse response = exchange.getResponse();

            if (response.getStatusCode() == HttpStatus.BAD_REQUEST) {
                return handleError(response, BaseErrorCode.PARAMETER_IS_INCORRECT_PLEASE_FILL_IN_AGAIN);
            } else if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
                return handleError(response, BaseErrorCode.REQUESTED_ADDRESS_IS_INCORRECT_PLEASE_FILL_IN_AGAIN);
            }

            return Mono.empty();
        }));
    }



    @Override
    public int getOrder() {
        // 控制过滤器的执行顺序，数值越小，优先级越高
        return 10;
    }

    private Mono<Void> handleError(ServerHttpResponse response, BaseErrorCode baseErrorCode) {
        // 检查响应是否已经提交
        if (!response.isCommitted()) {
            // 只有在响应未提交的情况下，才可以修改头信息
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        }
        ResultInfo resultInfo = ResultInfo.error(baseErrorCode);
        DataBuffer buffer = response.bufferFactory().wrap(JSON.toJSONString(resultInfo).getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Mono.just(buffer));
    }

}
